package com.zyy.game.tianlong.constant;

import com.zyy.game.tianlong.network.exception.ApiException;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 比牌工具类，传入的牌组必须为从大到小排序后的
 *
 * @author relufi
 * @date 2019/8/3 0003
 */
public class CardUtils {
    private CardUtils() {
    }

    /**
     * 特殊牌
     */
    public static final int TE_SHU = 0;

    /**
     * 单张
     */
    public static final int GAO_PAI = 1;
    /**
     * 对子
     */
    public static final int DUI_ZI = 2;
    /**
     * 顺子
     */
    public static final int SHUN_ZI = 3;
    /**
     * 金花
     */
    public static final int JIN_HUA = 4;
    /**
     * 同花顺
     */
    public static final int TONG_HUA_SHUN = 5;
    /**
     * 豹子
     */
    public static final int BAO_ZI = 6;


    public static boolean isBaoZi(Card[] cards) {
        return cards[0].number == cards[1].number && cards[0].number == cards[2].number;
    }

    public static boolean isTongHuaShun(Card[] cards) {
        return isShunZi(cards) && isJinHua(cards);
    }

    public static boolean isShunZi(Card[] cards) {
        if (cards[0].number == 14 && cards[1].number == 3 && cards[2].number == 2) {
            return true;
        }
        int cardNum = cards[2].number + 1;
        return cardNum == cards[1].number && cardNum + 1 == cards[0].number;
    }

    public static boolean isJinHua(Card[] cards) {
        return cards[0].color == cards[1].color && cards[0].color == cards[2].color;
    }

    public static boolean isDuiZi(Card[] cards) {
        return cards[0].number == cards[1].number || cards[1].number == cards[2].number;
    }

    public static boolean isTeShu(Card[] cards) {
        return cards[2].number == 2 && cards[1].number == 3 && cards[0].number == 5;
    }

    /**
     * 判断牌组是否为此类型
     *
     * @param type  牌组类型
     * @param cards 牌组
     * @return 是否正确
     */
    public static boolean isType(int type, Card[] cards) {
        switch (type) {
            case TE_SHU:
                return isTeShu(cards);
            case GAO_PAI:
                return isDanZhang(cards);
            case DUI_ZI:
                return isDuiZi(cards);
            case SHUN_ZI:
                return isShunZi(cards);
            case JIN_HUA:
                return isJinHua(cards);
            case TONG_HUA_SHUN:
                return isTongHuaShun(cards);
            case BAO_ZI:
                return isBaoZi(cards);
            default:
                return false;
        }
    }

    /**
     * 获取牌组的类型
     *
     * @param cards 牌组
     * @return 类型
     */
    public static int ofType(Card[] cards) {
        if (isTeShu(cards)) {
            return TE_SHU;
        }
        if (isJinHua(cards)) {
            if (isShunZi(cards)) {
                return TONG_HUA_SHUN;
            } else {
                return JIN_HUA;
            }
        } else if (isShunZi(cards)) {
            if (isJinHua(cards)) {
                return TONG_HUA_SHUN;
            } else {
                return SHUN_ZI;
            }
        } else if (isDuiZi(cards)) {
            if (isBaoZi(cards)) {
                return BAO_ZI;
            } else {
                return DUI_ZI;
            }
        } else {
            return GAO_PAI;
        }
    }


    public static boolean isDanZhang(Card[] cards) {
        return !isBaoZi(cards) &&
                !isTongHuaShun(cards) &&
                !isShunZi(cards) &&
                !isJinHua(cards) &&
                !isDuiZi(cards);
    }


    /**
     * 比较玩家牌组 传入的牌组必须是排序后的 从大到小 [max,middle,min]
     *
     * @param aType  A玩家牌组类型
     * @param aCards A牌组
     * @param bType  B玩家牌组类型
     * @param bCards B牌组
     * @return true : A玩家大   false: B玩家大
     */
    public static boolean compare(int aType, Card[] aCards, int bType, Card[] bCards) {
        // 特殊牌
        if (aType == TE_SHU && bType == BAO_ZI) {
            return bCards[0].number == 14;
        } else if (bType == TE_SHU && aType == BAO_ZI) {
            return aCards[0].number != 14;
        }else if(aType == bType){
//            金花 高牌 特殊牌 （乱牌 比较： 从大到小顺序点数 - 点数最大的颜色）
            if (aType == JIN_HUA || aType == GAO_PAI || aType == TE_SHU) {
//                if A(max) > B(max) return true
                return (aCards[0].number > bCards[0].number) ||
//                        if A(max) < B(max) false      if A(middle) > B(middle) return true
                        (aCards[0].number == bCards[0].number && ((aCards[1].number > bCards[1].number) ||
//                                if A(middle) < B(middle) false    if A(min) > B(min) return true
                                (aCards[1].number == bCards[1].number && (aCards[2].number > bCards[2].number ||
//                                        if A(min) < B(min) false      if A(max)(color) > B(max)(color) return true    if A(max)(color) < B(max)(color) return false
                                        (aCards[2].number == bCards[2].number && (aCards[0].color > bCards[0].color))))));
//            同花顺 顺子  （连续牌 比较： 最小的点数 - 点数最大的颜色）
            } else if (aType == TONG_HUA_SHUN || aType == SHUN_ZI) {
//                if A(min) > B(min) return true
                return (aCards[2].number > bCards[2].number) ||
//                        if A(min) < B(min) false      if A(max)(color) > B(max)(color) return true    if A(max)(color) < B(max)(color) return false
                        ((aCards[2].number == bCards[2].number) && (aCards[0].color > bCards[0].color));
//             对子 (对子，比较： 对子的点数 - 单牌点数  - 对子中颜色最大的颜色)
            } else if (aType == DUI_ZI) {
                int aDuiZi;
                int aDanPai;
                int aMaxColor;
                if (aCards[0].number == aCards[1].number) {
                    aDuiZi = aCards[0].number;
                    aDanPai = aCards[2].number;
                    aMaxColor = Math.max(aCards[0].color, aCards[1].color);
                } else {
                    aDuiZi = aCards[1].number;
                    aDanPai = aCards[0].number;
                    aMaxColor = Math.max(aCards[1].color, bCards[2].color);
                }
                int bDuiZi;
                int bDanPai;
                int bMaxColor;
                if (bCards[0].number == bCards[1].number) {
                    bDuiZi = bCards[0].number;
                    bDanPai = bCards[2].number;
                    bMaxColor = Math.max(bCards[0].color, bCards[1].color);
                } else {
                    bDuiZi = bCards[1].number;
                    bDanPai = bCards[0].number;
                    bMaxColor = Math.max(bCards[1].color, bCards[2].color);
                }
                return (aDuiZi > bDuiZi) || (aDuiZi == bDuiZi && (aDanPai > bDanPai || (aDanPai == bDanPai && aMaxColor > bMaxColor)));
//            豹子 （比较： 任意一张比较）
            } else if (aType == BAO_ZI) {
                return aCards[0].number > bCards[0].number;
            } else {
                throw new ApiException("炸金花牌组类型错误");
            }
        }else {
            return aType > bType;
        }
    }
    public static void sort(Card[] newCards) {
        if (newCards[0].compareTo(newCards[1])) {
            Card card = newCards[0];
            newCards[0] = newCards[1];
            newCards[1] = card;
        }
        if (newCards[1].compareTo(newCards[2])) {
            Card card = newCards[1];
            newCards[1] = newCards[2];
            newCards[2] = card;
        }
        if (newCards[0].compareTo(newCards[1])) {
            Card card = newCards[0];
            newCards[0] = newCards[1];
            newCards[1] = card;
        }
    }
    public static int maxIndex(Card[][] cards){
        List<Card[]> cards1 = Arrays.asList(cards);
        return cards1.indexOf(Collections.max(cards1, (o1, o2) -> compare(ofType(o1), o1, ofType(o2), o2) ? 1 : 0));
    }
}
